package com.pig4cloud.pig.demo.Controller;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.annotation.Inner;
import com.pig4cloud.pig.demo.Service.UserService;
import com.pig4cloud.pig.demo.Util.CheckEmailAndPhoneUtil;
import com.pig4cloud.pig.demo.Util.RedisUtil;
import com.pig4cloud.pig.demo.Util.TokenUtils;
import com.pig4cloud.pig.demo.feign.Entity.LoginForm;
import com.pig4cloud.pig.demo.feign.Entity.RegisterForm;
import com.pig4cloud.pig.demo.feign.Entity.User;
import com.pig4cloud.pig.demo.feign.Util.JWTUtil;
import com.pig4cloud.pig.demo.feign.Util.RandomUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
@Inner
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @GetMapping("/findAll")
    public R findAll() {
        return R.ok(userService.findAll());
    }

    @PostMapping("/login")
    public R login(@RequestBody LoginForm loginForm) {
        String token = userService.login(loginForm);
        if (token != null)
            return R.ok(token);
        return R.failed();
    }

//    @GetMapping("/getToken/{token}")
//    public R getToken(@PathVariable String token){
//        DecodedJWT verify = JWTUtil.verify(token);
//
//        System.out.println(verify.getClaim("id").asString());
//        return R.failed();
//    }

    @GetMapping("/getUserInfo")
    public R getUserInfo(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token))
            return R.failed();

        DecodedJWT verify = JWTUtil.verify(token);
        if (verify == null)
            return R.failed();

        User user = userService.findById(Long.parseLong(verify.getClaim("id").asString()));
        if (user == null)
            return R.failed("id无效");

        return R.ok(user);
    }

    @GetMapping("/msgLogin/{phone}")
    public R msgLogin(@PathVariable String phone) {
        if (StringUtils.isEmpty(phone))
            return R.failed("手机号不能为空");

        User user = userService.findPhoneNumber(phone);
        if (user == null)
            return R.failed("用户不存在");

        String code = redisTemplate.opsForValue().get(phone);

        if (!StringUtils.isEmpty(code)) {
            return R.ok();
        }

        code = RandomUtil.getFourBitRandom();
        Map<String, String> para = new HashMap<String, String>();
        para.put("code", code);

        boolean isSend = userService.msgSend(phone, para);
        if (isSend) {
            redisTemplate.opsForValue().set(phone, code, 5, TimeUnit.MINUTES);
            return R.ok();
        } else {
            return R.failed("短信发送失败");
        }
    }

    @GetMapping("/checkCode/{phone}/{code}")
    public R checkCode(@PathVariable String phone, @PathVariable String code) {
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code))
            return R.failed();

        String res = redisTemplate.opsForValue().get(phone);
        if (code.equals(res)) {
            User phoneNumber = userService.findPhoneNumber(phone);
            return R.ok(phoneNumber);
        }
        return R.failed();
    }

    @PostMapping("/register")
    public R register(@RequestBody RegisterForm form) {
        if (userService.findPhoneNumber(form.getPhone().toString()) != null)
            return R.failed();

        User user = new User();
        user.setUsername(form.getUsername());
        user.setPassword(form.getPassword());
        user.setPhone(form.getPhone());
        user.setAccount(form.getAccount());


        int i = userService.insert(user);
        if (i == 0)
            return R.failed();
        return R.ok(user);
    }

    /**
     * 通过id查询用户信息
     * @param id id
     * @return R
     */
    @Inner(value = false)
    public R getUserById(Long id) {
        User user = userService.getById(id);
        //将数据存到redis
        RedisUtil.set("user-" + id, user, redisTemplate);
        return R.ok(user);
    }

    /**
     * 通过redis获取用户信息
     */
    @Inner(value = false)
    @GetMapping("/getUser" )
    public R getUserByRedis(HttpServletRequest request) {
        Long id = TokenUtils.getId(request);
        if (id == null) {
            return R.failed("用户id为空");
        }
        User user = null;
        try {
            user = RedisUtil.get("user-" + id, User.class, redisTemplate);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        //如果根据key没有在redis获取到值，则查询mysql
        if (user == null) {
            return getUserById(id);
        }
        return R.ok(user);
    }

    /**
     * 修改用户信息
     * @param user
     * @return
     */
    @Inner(value = false)
    @PostMapping("/update/info")
    public R update(@RequestBody User user) {
        if (user == null) {
            return R.failed("参数错误");
        }
        String email = user.getEmail();
        Long phone = user.getPhone();
        if (CheckEmailAndPhoneUtil.checkEmail(email)) {
            R.failed("邮箱格式有误");
        }
        if (CheckEmailAndPhoneUtil.checkPhone(phone)) {
            R.failed("电话格式有误");
        }
        Long id = user.getId();
        if (id != null) {
            //修改数据库用户信息
            userService.updateById(user);
            redisTemplate.delete("user-" + id);
            //返回修改后的数据
            return getUserById(id);
        }
        return R.failed("参数错误");
    }
}
